import React, { type MouseEventHandler } from "react";
import { useComponentConfigStore } from "../../store/component-config";
import { useComponetsStore } from "../../store/components";
import type { Component } from "../../store/components";
import { useState } from "react";
import HoverMask from "../HoverMask";
import SelectedMask from "../SelectedMasks";
//画布区根组件
export function EditArea() {
    // 从组件存储中获取组件列表和添加组件的方法
    const { components, curComponentId, setCurComponentId } = useComponetsStore();
    // 获取组件配置信息
    const { componentConfig } = useComponentConfigStore();

    // 根据json组件树递归渲染组件树，并传入对应数据
    function renderComponents(components: Component[]): React.ReactNode {
        return components.map((component: Component) => {
            // 根据组件名称获取对应的配置
            const config = componentConfig?.[component.name]

            // 如果没有找到组件配置，则不渲染
            if (!config?.dev) {
                return null;
            }
            
            // 使用React.createElement动态创建组件实例，并传入对应的属性
            return React.createElement(
                config.dev,
                {
                    key: component.id,
                    id: component.id,
                    name: component.name,
                    styles: component.styles,
                    ...config.defaultProps,  // 应用默认属性
                    ...component.props,      // 应用自定义属性
                },
                renderComponents(component.children || [])  // 递归渲染子组件
            )
        })
    }

    //处理组件hover事件
    const [hoverId, setHoverId] = useState<number>();
    const handleMouseOver = (e: React.MouseEvent) => {
        const path = e.nativeEvent.composedPath()
        // composedPath 是从触发事件的元素到 html 根元素的路径（取原生事件）

        for (let i = 0; i < path.length; i++) {
            const ele = path[i] as HTMLElement;

            const componentId = ele.dataset?.componentId;//记得在组件dom元素那把id传过来
            // ele.dataset是一个 dom 的属性，包含所有 data-xx 的属性的值
            // 如果有data-xx的值的话，就把它赋值给componentId
            if (componentId) {
                setHoverId(+componentId)//设置当前hover的id为componentId
                return
            }
        }
    }

    //处理组件的click事件
    const handleClick: MouseEventHandler = (e) => {
        const path = e.nativeEvent.composedPath();

        for (let i = 0; i < path.length; i++) {
            const ele = path[i] as HTMLElement;

            const componentId = ele.dataset?.componentId;
            if (componentId) {
                setCurComponentId(+componentId)//设置当前选中的组件id为componentId
                return
            }
        }
    }
        
    return <div
        className="h-[100%] edit-area"
        onMouseOver={handleMouseOver}
        onMouseLeave={() => { setHoverId(undefined) }}//离开的时候不显示hover
        onClick={handleClick}

    >
        {/* 画布中渲染组件*/}
        {renderComponents(components)}
        {hoverId && hoverId!==curComponentId && (
            <HoverMask
                containerClassName="edit-area"
                portalWrapperClassName='portal-wrapper'
                componentId={hoverId}
            />
        )}
        {curComponentId && (
            <SelectedMask
                containerClassName="edit-area"
                portalWrapperClassName='portal-wrapper'
                componentId={curComponentId}
            />
        )}
        <div className="portal-wrapper"></div>
    </div>
}